from datetime import datetime

import pytz
from alipay import AliPay
from flask import Blueprint, request, jsonify, render_template, session, redirect, flash, url_for, current_app
from applications.models.frontend import Product, Cart, User, Address, Order, OrderItem
from applications.extensions import db
from applications.view.user.decorators import login_required # 从新的模块导入装饰器
# 创建购物车管理蓝图
cart_bp = Blueprint('cart', __name__)

# 前台添加到购物车
@cart_bp.route('/add_to_cart/<int:product_id>', methods=['GET', 'POST'])
@login_required
def add_to_cart(product_id):
    # 检查花是否存在
    product = Product.query.get(product_id)
    if not product:
        flash('该商品不存在！', 'danger')
        return redirect(url_for('user.product'))

    # 检查购物车中是否已存在该花
    cart_item = Cart.query.filter_by(user_id=session['user_id'], product_id=product_id).first()
    if cart_item:
        # 如果已存在，增加数量
        cart_item.quantity += 1
    else:
        # 如果不存在，添加新项
        cart_item = Cart(user_id=session['user_id'], product_id=product_id, quantity=1)
        db.session.add(cart_item)

    db.session.commit()
    flash('已成功添加到购物车！', 'success')
    return redirect(url_for('cart.cart'))

# 前台更新购物车
@cart_bp.route('/update_cart/<string:product_id>', methods=['POST'])
def update_cart(product_id):
    # 获取用户提交的花的数量，并将其转换为整数。如果用户没有提供数量，则默认值为1
    quantity = int(request.form.get('quantity', 1))
    user_id = session.get('user_id')

    if user_id:
        cart_item = Cart.query.filter_by(user_id=user_id, product_id=product_id).first()
        if cart_item:
            if quantity > 0:
                cart_item.quantity = quantity  # 更新数量
            else:
                db.session.delete(cart_item)  # 删除购物车项
        db.session.commit()  # 提交更改
    else:
        # 如果用户未登录，更新 session 中的购物车
        if 'cart' in session and product_id in session['cart']:
            if quantity > 0:
                session['cart'][product_id] = quantity  # 更新数量
            else:
                session['cart'].pop(product_id)  # 删除购物车项
        session.modified = True
    return jsonify(success=True)  # 返回 JSON 响应

# 前台删除购物车
@cart_bp.route('/remove_from_cart/<string:product_id>')
def remove_from_cart(product_id):
    user_id = session.get('user_id')
    if user_id:
        cart_item = Cart.query.filter_by(user_id=user_id, product_id=product_id).first()
        if cart_item:
            db.session.delete(cart_item)  # 从数据库中删除购物车项
            db.session.commit()  # 提交更改
    else:
        # 如果用户未登录，更新 session 中的购物车
        if 'cart' in session and product_id in session['cart']:
            session['cart'].pop(product_id)
            session.modified = True
    return redirect(url_for('cart.cart'))

# 前台清空购物车
@cart_bp.route('/clear_cart')
def clear_cart():
    user_id = session.get('user_id')
    if user_id:
        # 删除该用户的所有购物车项
        Cart.query.filter_by(user_id=user_id).delete()
        db.session.commit()
    # 同时清除session中的购物车数据
    session.pop('cart', None)
    session.modified = True
    return redirect(url_for('cart.cart'))


# 前台购物车结算页面
@cart_bp.route('/checkout', methods=['GET', 'POST'])
@login_required
def checkout():
    user_id = session.get('user_id')
    users = User.query.get(user_id)
    if request.method == 'POST':
        # 处理新增地址的请求
        if request.form.get('action') == 'add_address':
            recipient_name = request.form.get('recipient_name')
            phone = request.form.get('phone')
            address_line = request.form.get('address_line')

            # 创建新地址
            new_address = Address(
                user_id=user_id,
                recipient_name=recipient_name,
                phone=phone,
                address_line=address_line
            )
            db.session.add(new_address)
            db.session.commit()

            flash('收货地址添加成功！', 'success')
            return redirect(url_for('cart.checkout'))
        # 处理支付请求
        address_id = request.form.get('address_id')
        order_id = request.form.get('order_id')  # 获取订单 ID（用于再次支付）

        # 如果是再次支付，直接获取已有订单
        if order_id:
            order = Order.query.filter_by(id=order_id, user_id=user_id).first()
            cart_items = Cart.query.filter_by(user_id=user_id).all()
            # 添加订单详情项
            for item in cart_items:
                product = Product.query.get(item.product_id)
                order_item = OrderItem(
                    order_id=order.id,
                    product_id=item.product_id,
                    quantity=item.quantity,
                    price=product.price
                )
                db.session.add(order_item)
            print('直接获取已有订单order', order)
            if not order:
                flash('订单不存在或不属于当前用户！', 'danger')
                return redirect(url_for('user.orders'))
        else:
            # 创建新订单的逻辑
            selected_address = Address.query.get(address_id)
            if not selected_address:
                flash('请选择有效的收货地址！', 'danger')
                return redirect(url_for('cart.checkout'))

            cart_items = Cart.query.filter_by(user_id=user_id).all()
            if not cart_items:
                flash('购物车为空！', 'danger')
                return redirect(url_for('cart.cart'))
            try:
                # 计算订单总金额
                total_amount = sum(item.quantity * item.product.price for item in cart_items)

                # 创建订单对象
                shanghai_tz = pytz.timezone('Asia/Shanghai')
                current_time = datetime.now(shanghai_tz)
                order = Order(
                    user_id=user_id,
                    status='unpaid',  # 修改初始状态为 unpaid
                    order_time=current_time,
                    address=selected_address.address_line,
                    recipient_name=selected_address.recipient_name,
                    phone=selected_address.phone,
                    total_amount=total_amount  # 设置订单总金额
                )
                db.session.add(order)
                db.session.flush()  # 获取order.id但不提交事务

                # 添加订单详情项
                for item in cart_items:
                    product = Product.query.get(item.product_id)
                    order_item = OrderItem(
                        order_id=order.id,
                        product_id=item.product_id,
                        quantity=item.quantity,
                        price=product.price
                    )
                    db.session.add(order_item)

            except Exception as e:
                current_app.logger.error(f"订单创建失败: {str(e)}")
                db.session.rollback()
                flash('订单创建失败，请重试', 'danger')
                return redirect(url_for('cart.checkout'))

        # 生成支付链接
        alipay_config = current_app.config['ALIPAY']
        alipay = AliPay(
            appid=alipay_config['APP_ID'],
            app_notify_url=alipay_config['APP_NOTIFY_URL'],
            app_private_key_string=alipay_config['APP_PRIVATE_KEY'],
            alipay_public_key_string=alipay_config['ALIPAY_PUBLIC_KEY'],
            sign_type=alipay_config['SIGN_TYPE'],
            debug=alipay_config['DEBUG']
        )

        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=str(order.id),
            total_amount=str(order.total_amount),
            subject=f"花店订单-{order.id}",
            return_url=alipay_config['RETURN_URL'],
            notify_url=alipay_config['APP_NOTIFY_URL']
        )
        # 清空与该订单关联的购物车项
        Cart.query.filter_by(user_id=order.user_id).delete()  # 新增
        db.session.commit()

        # 重定向到支付宝
        pay_url = alipay_config['GATEWAY'] + order_string
        return redirect(pay_url)

    # GET 请求处理
    addresses = Address.query.filter_by(user_id=session.get('user_id')).all()
    return render_template('user/checkout.html', addresses=addresses, user=users)
# 支付成功回调通知
@cart_bp.route('/payment/notify', methods=['POST'])
def payment_notify():
    try:
        data = request.form.to_dict()
        alipay_config = current_app.config['ALIPAY']
        alipay = AliPay(
            appid=alipay_config['APP_ID'],
            app_private_key_string=alipay_config['APP_PRIVATE_KEY'],
            alipay_public_key_string=alipay_config['ALIPAY_PUBLIC_KEY'],
            sign_type=alipay_config['SIGN_TYPE'],
            debug=alipay_config['DEBUG']
        )

        # 验证支付宝的通知
        signature = data.pop('sign')
        success = alipay.verify(data, signature)
        print("支付成功回调通知：", data)
        print("支付成功回调通知111：", success, data["trade_status"])

        if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
            order_id = data.get('out_trade_no')
            order = Order.query.get(order_id)
            if order and order.status != 'paid':
                order.status = 'paid'
                order.payment_time = datetime.now()
                db.session.commit()
                print(f"订单 {order_id} 支付成功")
                return 'success'
        return 'failed'
    except Exception as e:
        current_app.logger.error(f"支付回调处理错误: {str(e)}")
        return 'failed'

# 支付结果同步通知
@cart_bp.route('/payment/return', methods=['GET'])
def payment_return():
    try:
        data = request.args.to_dict()
        alipay_config = current_app.config['ALIPAY']
        alipay = AliPay(
            appid=alipay_config['APP_ID'],
            app_private_key_string=alipay_config['APP_PRIVATE_KEY'],
            alipay_public_key_string=alipay_config['ALIPAY_PUBLIC_KEY'],
            sign_type=alipay_config['SIGN_TYPE'],
            debug=alipay_config['DEBUG']
        )

        signature = data.pop('sign')
        success = alipay.verify(data, signature)
        print("支付结果同步通知：", data)
        print("支付结果同步通知111：", success)
        if success:
            order_id = data.get('out_trade_no')
            order = Order.query.get(int(order_id))  # 强制转换为整数
            if order:
                # 防止重复清空
                if Cart.query.filter_by(user_id=order.user_id).first():
                    Cart.query.filter_by(user_id=order.user_id).delete()
                if order.status == 'paid':
                    flash('该订单已支付成功，请勿重复支付！', 'info')
                else:
                    order.status = 'paid'  # 更新订单状态为已支付
                    db.session.commit()
                    flash('支付成功！', 'success')
                return redirect(url_for('user.order_detail', order_id=order_id))
            else:
                flash('订单不存在！', 'danger')
                return redirect(url_for('cart.cart'))
        else:
            flash('支付验证失败！', 'danger')
            return redirect(url_for('cart.cart'))
    except Exception as e:
        current_app.logger.error(f"支付返回处理错误: {str(e)}")
        flash('支付处理出错，请联系客服', 'danger')
        return redirect(url_for('cart.cart'))

# 前台购物车页面路由
@cart_bp.route('/cart')
def cart():
    print('Current session in cart:', session)  # Debugging line
    user_id = session.get('user_id')
    user = User.query.get(user_id)
    cart_items = []
    total = 0

    if user_id:
        # 从数据库中获取购物车项
        cart_items_db = Cart.query.filter_by(user_id=user_id).all()
        for item in cart_items_db:
            product = Product.query.get(item.product_id)
            if product:
                item_total = product.price * item.quantity
                total += item_total
                cart_items.append({
                    'id': product.id,
                    'name': product.name,
                    'price': product.price,
                    'quantity': item.quantity,
                    'total': item_total
                })
    else:
        # 如果用户未登录，使用 session 中的购物车数据
        if 'cart' in session:
            for product_id, quantity in session['cart'].items():
                product = Product.query.get(product_id)
                if product:
                    item_total = product.price * quantity
                    total += item_total
                    cart_items.append({
                        'id': product.id,
                        'name': product.name,
                        'price': product.price,
                        'quantity': quantity,
                        'total': item_total
                    })
    return render_template('user/shopCart/cart.html', user=user, cart_items=cart_items, total=total)

# 注册购物车管理蓝图
def register_cart_bps(app):
    app.register_blueprint(cart_bp, url_prefix='/cart')
